<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <script
      type="application/javascript"
      src="../../static/plugins/jquery/jquery-3.3.1.min.js"
    ></script>
  </head>
  <body>
    <button>测试1</button>
    <br />
    <button>测试2</button>
    <br />
    <button>测试3</button>

    <script>
      //对象的解构赋值
      let obj = { usernam: "kobe", age: 25 };
      let { age } = obj;
      console.log(age);

      //数组的解构赋值
      let arr = [1, 3, 4, 5, "aa"];
      let [a, b] = arr;
      console.log(a, b);

      /**
       * 模板字符串 : 简化字符串的拼接
       * 模板字符串必须用 `` 包含
       * 变化的部分使用${xxx}定义
       */
      let str = `我的名字叫：${obj.usernam}, 年龄是: ${obj.age}`;
      console.log(str);

      let email = "1506074570@qq.com";
      let phone = 13786231507;

      let info = {
        email,
        phone,
        getName() {
          return this.phone;
        },
      };
      console.log(info);

      /**
       * 箭头函数this的特点：
       * 1.箭头函数没有自己的this，箭头函数的this不是调用的时候决定的，而是在定义的时候处在的对象就是它的this
       * 2.扩展的理解：箭头函数的this看外层的时候有函数
       *               如果有，外层函数的this就是内部箭头函数的this
       *               如果没有, 则this就是window
       * */
      //无形参的时候
      let fun = () => console.log("这是箭头函数");
      fun();

      //只有一个形参的时候()可省略
      let fun2 = (a) => console.log(a);
      fun2("aaaa");

      //形参有两个的时候
      let fun3 = (x, y) => console.log(x, y);
      fun3(20, 31);

      //箭头函数：函数体的情况
      //函数体只有一条语句或者是表达式的时候，{}可以省略
      let fun4 = (x, y) => {
        console.log(fun4(x + y));
      };

      /**
       * 扩展运算符：...
       * */
      //数组复制1
      let array = [1, 3, 4, 6];
      let arr2 = [...array];
      console.log(arr2);

      //数组复制2
      let arr3 = [];
      Object.assign(arr3, array);
      console.log(arr3);

      //数组复制3
      let arr4 = array.slice();
      console.log(arr4);

      //数组的复制4
      let arr5 = array.concat();
      console.log(arr5);

      //数组插入：
      let insertArr = [12, 34, 56];
      let newArray = [1, ...insertArr, 3, 4, 6];
      console.log(newArray);

      /**
       * Symbol
       * 特点：
       * 1、Symbol属性对应的值是唯一的，解决命名冲突问题
       * 2、Symbol值不能与其他数据进行计算，包括同字符串拼串
       * 3、for in, for of遍历时不会遍历symbol属性。
       * */
      //创建symbol属性值
      let symbol = Symbol();

      /**
    * async函数(源自ES2017)
    * 概念： 真正意义上去解决异步回调的问题，同步流程表达异步操作
    * 本质： Generator的语法糖
    * 语法：
    *  async function foo(){
          await 异步操作;
          await 异步操作；
       }
    *  特点：
    *   1、不需要像Generator去调用next方法，遇到await等待，当前的异步操作完成就往下执行
    *   2、返回的总是Promise对象，可以用then方法进行下一步操作
    *   3、async取代Generator函数的星号*，await取代Generator的yield
    *   4、语意上更为明确，使用简单，经临床验证，暂时没有任何副作用
    * */
      async function foo() {
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve();
          }, 2000);
        });
      }

      async function test() {
        console.log("开始执行" + new Date().toTimeString());
        await foo();
        // console.log('执行完毕' + new Date().toTimeString())
      }
      test();

      /**
       * class类：
       * 1. 通过class定义类/实现类的继承
       * 2. 在类中通过constructor定义构造方法
       * 3. 通过new来创建类的实例
       * 4. 通过extends来实现类的继承
       * 5. 通过super调用父类的构造方法
       * 6. 重写从父类中继承的一般方法
       * */
      class Person {
        constructor(name, age) {
          this.name = name;
          this.age = age;
        }

        showName() {
          console.log("父类的方法");
        }
      }

      let person = new Person("kobe", 26);
      console.log(person);

      //类的继承
      class StarPerson extends Person {
        constructor(name, age, salary) {
          super(name, age);
          this.salary = salary;
        }
      }
      let p1 = new StarPerson("kobe", 27, 56000);
      console.log(p1);

      /**
       * 数组的扩展：
       * 1. Array.from(v) : 将伪数组对象或可遍历对象转换为真数组
       * 2. Array.of(v1, v2, v3) : 将一系列值转换成数组
       * 3. find(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素
       * 4. findIndex(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素下标
       */
      //得到的btns是一个伪数组
      let btns = document.getElementsByTagName("button");
      //1. Array.from(v) : 将伪数组对象或可遍历对象转换为真数组
      Array.from(btns).forEach((item) => {
        console.log(item);
      });

      //2. Array.of(v1, v2, v3) : 将一系列值转换成数组
      let aa = Array.of(1, 2, "56", 9);
      console.log(aa);

      //3. find(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素
      let bb = [2, 3, 4, 2, 7, 3, 6, 5];
      let result = bb.findIndex((item, index) => {
        return item > 4;
      });
      console.log(result);

      /**
   * 对象的扩展：
   * 1. Object.is(v1, v2)
   *    判断2个数据是否完全相等
   * 2. Object.assign(target, source1, source2..)
   *    将源对象的属性复制到目标对象上
   * 3. 直接操作 __proto__ 属性
        let obj2 = {};
        obj2.__proto__ = obj1;
   * */
      let ob = [1, 2, 3, 4];
      let ob2 = [];
      // Object.assign(ob2, ob)
      // console.log(ob2)
      ob2.__proto__ = ob;
      console.log(ob2);
    </script>
  </body>
</html>
